Skip to content

fix(i18n): Windows 下语言设置与跟随系统不生效 - #4

Merged
Sam-Fic merged 2 commits into
mainfrom
fix/win-i18n-language-setting
Nov 10, 2026
Merged

Sam-Fic merged 2 commits into
mainfrom
fix/win-i18n-language-setting

Conversation

@Sam-Fic

@Sam-Fic Sam-Fic commented Nov 10, 2026

Copy link
Copy Markdown
Owner

问题

Windows 便携包 (v4.10.0 实测): 偏好设置里选「中文」重启后 UI 仍是英文;中文 Windows 上「跟随系统」也一直英文。

根因

GNU gettext 只在当前 locale 非 "C" 时才读取 LANGUAGE。此 Windows gettext 构建在没有 LANG/LC_* 环境变量时 locale 落回 "C"(Win32 locale 回退无效),因此:

  • 设置只写 LANGUAGE=zh_CN → 被整体忽略(包内 zh_CN.mo 完好,49KB 全量译文已验证);
  • 「跟随系统」同样受害:中文 Windows 上也拿不到系统语言 → 英文。

本机 (zh-CN Windows) 用 4.10.0 便携包 CLI 实测矩阵:

环境变量 结果
LANGUAGE=zh_CN 英文 ❌
LANG=zh_CN / LC_MESSAGES=zh_CN / LC_ALL=zh_CN.UTF-8 中文 ✅
LANG=en LANGUAGE=zh_CN 中文 ✅(locale 非 C 时 LANGUAGE 生效)
LANGUAGE=zh_CN LANG=zh_CN.UTF-8(修复后 zh 分支) 中文 ✅
LANGUAGE=en LANG=en(修复后 en 分支) 英文 ✅

修复

  • src/main.vala(仅 #if WINDOWS):显式 zh/en 时同时设 LANG;「跟随系统」用 g_win32_getlocale() 把 Windows 用户 locale(zh-CN → zh_CN)写入 LANG,并无条件覆盖以避免重启子进程继承残留。
  • tools/build-windows-package.sh:新增 i18n 运行时冒烟——打包后真实运行 --help(LANG=zh_CN.UTF-8)断言输出「命令行模式」,防止 gettext 链再断而清单校验照过。
  • docs/I18N.md:补充 Windows 下 LANGUAGE 无效、须用 LANG 的说明。

验证

  • 本机用 v4.10.0 便携包解包复现根因,并实测修复后的环境变量组合(zh/en 两分支)。
  • CI Windows job 会编译 + 打包 + 运行新增冒烟测试。

根因 (本机 4.10.0 便携包实测复现):
- GNU gettext 只在当前 locale 非 "C" 时才读取 LANGUAGE; 该 Windows
  gettext 构建在无 LANG/LC_* 环境变量时 locale 落回 "C" (Win32 回退
  无效), LANGUAGE 被整体忽略。
- 偏好设置只写 LANGUAGE=zh_CN/en -> 永远英文 (包内 zh_CN.mo 完好)。
- "跟随系统"同样受害: 中文 Windows 上 locale 也落回 "C" -> 英文。

修复 (src/main.vala, 仅 Windows):
- 显式 zh/en: 同时设 LANG=zh_CN.UTF-8 / LANG=en, 让 locale 脱离 "C"。
  实测: 仅 LANGUAGE=zh_CN -> 英文; LANGUAGE=zh_CN + LANG=zh_CN.UTF-8
  -> 中文; 两分支 en 亦验证。
- 跟随系统: 用 g_win32_getlocale() 把 Windows 用户 locale (zh-CN)
  翻成 "zh_CN" 喂给 LANG; 无条件覆盖以避免重启继承残留旧值。

打包 (tools/build-windows-package.sh): 新增 i18n 运行时冒烟, 解包后
真实运行 --help (LANG=zh_CN.UTF-8) 断言中文输出, 防止 gettext 链
再断而清单校验照过的回归。

docs/I18N.md: 补充 Windows 下 LANGUAGE 无效、需用 LANG 的说明。
冒烟复检发现: g_win32_getlocale() 只要见到 LANG/LC_* 就原样返回其值,
只有全空才查 Windows (GetThreadLocale)。两处受害:
- 重启链路: 上一会话写入的 LANG=zh_CN.UTF-8 被原样返回, 拼成
  zh_CN.UTF-8.UTF-8 垃圾值 -> 切回"跟随系统"反而英文;
- Git Bash 启动: 其自带 LANG=C.UTF-8, 同样中招 (本机实测复现)。

修正: 取系统 locale 前临时摘掉 LANG/LC_ALL/LC_MESSAGES 强制走 Win32
路径; 引入 FILECOLLECTOR_LANG_MANAGED 标记区分应用自己写的 LANG
(重启链路, 无条件覆盖) 与外部真实语言设置 (尊重); "C"/"C.*"/
"POSIX" 视同未设置。
@Sam-Fic
Sam-Fic merged commit 0ddc716 into main Nov 10, 2026
7 checks passed
@Sam-Fic
Sam-Fic deleted the fix/win-i18n-language-setting branch November 10, 2026 18:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant